/*
 *  Copyright (C) void Team 2010 Pedro Batista
 * 
 *  http://code.google.com/p/capacitec
 * 
 *  This file is part of capacitec.
 * 
 *  capacitec is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  capacitec is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with capacitec.  If not, see <http://www.gnu.org/licenses/>.
 */
package seguranca;

import seguranca.anotacoes.RestritoCoordenador;
import seguranca.anotacoes.RestritoAdministrador;
import br.com.caelum.vraptor.InterceptionException;
import br.com.caelum.vraptor.Intercepts;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.core.InterceptorStack;
import br.com.caelum.vraptor.interceptor.Interceptor;
import br.com.caelum.vraptor.resource.ResourceMethod;
import controller.HomeController;
import seguranca.anotacoes.RestritoAluno;
import seguranca.anotacoes.RestritoLogado;

/**
 * Classe responsável por fazer verificações nos métodos chamados para saber
 * se o usuário tem permissões para executá-los.
 * @author pedro
 */
@Intercepts
public class AutorizacaoInterceptor implements Interceptor {

	private final Usuario usuario;
	private final Result result;

	/**
	 *
	 * @param usuario
	 * @param result
	 */
	public AutorizacaoInterceptor(Usuario usuario, Result result) {
		this.usuario = usuario;
		this.result = result;
	}

	/**
	 *
	 * @return Usuário logado no sistema.
	 */
	public Usuario getUsuario() {
		return usuario;
	}

	/**
	 * Intercepta a requisição de usuário e o redireciona para a tela de login.
	 * @param stack
	 * @param method
	 * @param resourceInstance
	 * @throws InterceptionException
	 */
	@Override
	public void intercept(InterceptorStack stack, ResourceMethod method, Object resourceInstance) throws InterceptionException {
		result.redirectTo(HomeController.class).login();
	}

	/**
	 * Verifica se o método chamado possui alguma restrição, caso positivo
	 * verifica se o usuário logado tem permissão para executá-lo caso positivo
	 * executa senão intercepta.
	 * @param method metodo sendo chamado.
	 * @return se positivo bloqueia senão aceita a execução do método.
	 */
	@Override
	public boolean accepts(ResourceMethod method) {
		boolean access = false;
		boolean mudou = false;

		if (!access && method.containsAnnotation(RestritoLogado.class)){
			access = usuario.isLogado();
			mudou = true;
		}
		if (!access && method.containsAnnotation(RestritoCoordenador.class)) {
			access = usuario.isCoordenador();
			mudou = true;
		}
		if (!access && method.containsAnnotation(RestritoAdministrador.class)) {
			access = usuario.isAdministrador();
			mudou = true;
		}
		if (!access && method.containsAnnotation(RestritoAluno.class)){
			access = usuario.isAluno();
			mudou = true;
		}

		return mudou ? !access : false;
	}
}
